Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

updated big-endian handling: now completely host-independent #3

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

neonsoftware
Copy link

Hi @mhroth,

This commit removes the use of platform-specific functions (htonll, htobe64).
Luckily knowing the endianness of the transport is sufficient to be able to encode and decode without any knowledge of the host's architecture.

The substituting functions are short, readable, vanilla C, and will build and be correct on any platform and architecture.
( all inspired by this Rob Pike's article on endianness, functions included )

I find that readability results to be also slightly improved, but that is, of course, completely subjective.

Please feel free to return any feedback or demand for any change or modify it.

Cheers 👍

@mhroth
Copy link
Owner

mhroth commented Jan 4, 2017

I've been giving this some though. I like the addition of bundle_id as it makes the code more readable. Regarding the host-independent endian ordering, what's the use case? Do you have an application which the existing includes do not support? It seems like we'd be reimplementing existing system-provided functionality.

@neonsoftware
Copy link
Author

neonsoftware commented Jan 5, 2017

I absolutely understand and agree on not reinventing the wheel when it's not the case. 100%.

For the use case, I actually run it on a teensy 3.1 board where there is basically no system. 😄

>> arm-none-eabi-gcc *.c -Werror -std=c99 -O0 -g -o tinyosc
tinyosc.c:25:24: fatal error: netinet/in.h: No such file or directory
compilation terminated.

But more generally, going towards C-only self sufficient code make it really universal and eternal, in always being able to build and run anywhere.
In the case of this library, it's super near to be dependency-less, the endianness code might worth its place (?)
cheers

@s-ol
Copy link

s-ol commented Jun 27, 2019

just ran into this on an Arduino as well; this did the trick for me as a quick fix:

#define htonl(x) ( ((x)<<24 & 0xFF000000UL) | \
                   ((x)<< 8 & 0x00FF0000UL) | \
                   ((x)>> 8 & 0x0000FF00UL) | \
                   ((x)>>24 & 0x000000FFUL) )
#define ntohl(x) htonl(x)

#define htonll(x) ( (uint64_t) htonl((uint32_t) x) << 32 | htonl(x>>32) )
#define ntohll(x) ntohll(x)

@agnunez
Copy link

agnunez commented Sep 26, 2019

Run into the same issue while building in a raspberry pi raspbian:
tinyosc.c: In function ‘tosc_isBundle’:
tinyosc.c:31:19: error: implicit declaration of function ‘htobe64’ [-Werror=implicit-function-declaration]
#define htonll(x) htobe64(x)
^~~~~~~
tinyosc.c:62:42: note: in expansion of macro ‘htonll’
return ((*(const int64_t ) buffer) == htonll(BUNDLE_ID));
^~~~~~
tinyosc.c: In function ‘tosc_getTimetag’:
tinyosc.c:32:19: error: implicit declaration of function ‘be64toh’ [-Werror=implicit-function-declaration]
#define ntohll(x) be64toh(x)
^~~~~~~
tinyosc.c:73:10: note: in expansion of macro ‘ntohll’
return ntohll(
((uint64_t *) (b->buffer+8)));
^~~~~~

I solved by suppressing -std=c99 option from build script as stated here:
https://stackoverflow.com/questions/19525378/be64toh-not-linking-or-being-declared-when-compiling-with-std-c99
as this options prevents to load GNU extensions, and now works.
I agree that clean code without dependences is nicer to have. thanks

@Paspartout
Copy link

Just a heads up for anyone using this PR/Modifications: I found that floats and doubles are wrongly encoded/swapped due to missing casts. They have to be casted like they have been before using encode_uint32_t(*((uint32_t *) &f), buffer + i); instead of encode_uint32_t(f, (buffer + i));:

      case 'f': {
        if (i + 4 > len) return -3;
        const float f = (float) va_arg(ap, double);
        encode_uint32_t(*((uint32_t *) &f), buffer + i);
        i += 4;
        break;
      }
      case 'd': {
        if (i + 8 > len) return -3;
        const double f = (double) va_arg(ap, double);
        encode_uint64_t(*((uint64_t *) &f), (buffer + i));
        i += 8;
        break;
      }

@lacasse4
Copy link

On Linux for Raspberry PI, I got the following message after running build.sh:

$ ./build.sh
tinyosc.c: In function ‘tosc_isBundle’:
tinyosc.c:30:19: error: implicit declaration of function ‘htobe64’ [-Werror=implicit-function-declaration]
   30 | #define htonll(x) htobe64(x)
      |                   ^~~~~~~
tinyosc.c:61:42: note: in expansion of macro ‘htonll’
   61 |   return ((*(const int64_t *) buffer) == htonll(BUNDLE_ID));
      |                                          ^~~~~~
tinyosc.c: In function ‘tosc_getTimetag’:
tinyosc.c:31:19: error: implicit declaration of function ‘be64toh’ [-Werror=implicit-function-declaration]
   31 | #define ntohll(x) be64toh(x)
      |                   ^~~~~~~
tinyosc.c:72:10: note: in expansion of macro ‘ntohll’
   72 |   return ntohll(*((uint64_t *) (b->buffer+8)));
      |          ^~~~~~
cc1: all warnings being treated as errors

using this version of Linux:

Distributor ID:	Raspbian
Description:	Raspbian GNU/Linux 11 (bullseye)
Release:	11
Codename:	bullseye

It seems the the -std=c99 switch in build.sh prevents the __USE_MISC to be defined in endian.h. That makes htobe64(x) and be64toh(x) unavailable at compile time.

I simply removed the -std-c99 switch and it seems to work. However, I don't know if there is any further considerations about removing this switch.

@neonsoftware
Copy link
Author

Hi @lacasse4 @Paspartout @agnunez @s-ol,

I just realized that I had never noticed, even once, within my Github notifications that your messages were about this PR of mine of 6 years ago, of which I had entirely forgotten.

I will re-check everything this weekend and see what is the current scenario (as the PR has now even conflicts)

Have a nice day you all.

@neonsoftware
Copy link
Author

@mhroth is the project maintained, as should I work on the PR ? Thank you in advance for confirmation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants